//
//  String+Ext.swift
//  
//
//  Created by bo wang on 2020/8/17.
//  Copyright © 2020 wangbo. All rights reserved.
//

import Foundation
import CommonCrypto

public extension String {
    var md5: String {
        let utf8 = cString(using: .utf8)!
        var digest = [UInt8](repeating: 0, count: Int(CC_MD5_DIGEST_LENGTH))
        CC_MD5(utf8, CC_LONG(utf8.count - 1), &digest)
        let result = digest.reduce("", { $0 + String(format: "%02x", $1) })
        return result
    }
}

public extension String {
    /// string[1..<5]
    subscript(_ range: Range<Int>) -> String? {
        if let start = index(startIndex, offsetBy: range.startIndex, limitedBy: endIndex),
            let end = index(startIndex, offsetBy: range.endIndex, limitedBy: endIndex) {
            return String(self[start..<end])
        }
        return nil
    }
    
    /// string[1...5]
    subscript(_ range: ClosedRange<Int>) -> String? {
        if let start = index(startIndex, offsetBy: range.lowerBound, limitedBy: endIndex),
            let end = index(startIndex, offsetBy: range.upperBound + 1, limitedBy: endIndex) {
            return String(self[start..<end])
        }
        return nil
    }

    /// string[..<5]
    subscript(_ range: PartialRangeUpTo<Int>) -> String? {
        return self[0..<range.upperBound]
    }

    /// string[...5]
    subscript(_ range: PartialRangeThrough<Int>) -> String? {
        return self[0...range.upperBound]
    }

    /// string[1...]
    subscript(_ range: PartialRangeFrom<Int>) -> String? {
        return self[range.lowerBound..<count]
    }
    
    /// string[1]
    subscript(_ index: Int) -> String? {
        return self[index...index]
    }
    
    /// string[range]
    subscript(_ range: NSRange) -> String? {
        guard let r = Range(range, in: self) else { return nil }
        return String(self[r])
    }
    
    var nsrange: NSRange {
        return NSRange(location: 0, length: utf16.count)
    }
    
    /// 将字符串保留数字内容
    var numericCharacters: String {
        return compactMap { $0.isNumber ? String($0) : nil }.joined()
    }
    
    /// 全拼
    var pinyin: String? {
        let str = applyingTransform(.mandarinToLatin, reverse: false)
        return str?.applyingTransform(.stripCombiningMarks, reverse: false)?.split(separator: " ").joined()
    }
    
    /// 全拼首字母
    var pinyinFirstLetter: String? {
        let firstLetters = self.compactMap { (c) -> String? in
            if let first = String(c).pinyin?.first {
                return String(first)
            }
            return nil
        }
        if firstLetters.isEmpty {
            return nil
        }
        return firstLetters.joined()
    }
    
    /// 去掉前后的指定字符。
    /// - Parameter str: 前后字符集，为nil时去掉空白
    mutating func trim(_ str: String? = nil) {
        self = trimmed(str)
    }
    
    /// 返回已经去掉前后的指定字符的新字符串。
    /// - Parameter str: 前后字符集，为nil时去掉空白
    /// - Returns: 新字符串
    func trimmed(_ str: String? = nil) -> String {
        if let s = str {
            return trimmingCharacters(in: CharacterSet(charactersIn: s))
        } else {
            return trimmingCharacters(in: .whitespacesAndNewlines)
        }
    }
}
